home *** CD-ROM | disk | FTP | other *** search
- TITLE INT3D - OBJECT/MOVE SPPT IN ASSEMBLER
-
- COMMENT $
-
-
- /* Routines for moving, scaling and rotating objects */
- /* Matrix math, assembly by Dave Stampe */
- /* converted to assembly 12/12/93 by Dave Stampe */
-
- ALL routines in this module by Dave Stampe
-
- /*
- This code is part of the VR-386 project, created by Dave Stampe.
- VR-386 is a desendent of REND386, created by Dave Stampe and
- Bernie Roehl. Almost all the code has been rewritten by Dave
- Stampre for VR-386.
-
- Copyright (c) 1994 by Dave Stampe:
- May be freely used to write software for release into the public domain
- or for educational use; all commercial endeavours MUST contact Dave Stampe
- (dstampe@psych.toronto.edu) for permission to incorporate any part of
- this software or source code into their products! Usually there is no
- charge for under 50-100 items for low-cost or shareware products, and terms
- are reasonable. Any royalties are used for development, so equipment is
- often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to VR-386 and Dave Stampe,
- and any other authors in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling!
-
- DEVELOPMENT: VR-386 is a effort to develop the process started by
- REND386, improving programmer access by rewriting the code and supplying
- a standard API. If you write improvements, add new functions rather
- than rewriting current functions. This will make it possible to
- include you improved code in the next API release. YOU can help advance
- VR-386. Comments on the API are welcome.
-
- CONTACT: dstampe@psych.toronto.edu
- */
- $
-
- .MODEL large
-
- ; # define XFSC 536870912 /* 2**29 for shifting xform coeffs to long */
-
-
- .DATA
-
- include 3dstruct.inc
-
- extrn _sqrtable ; pointer to 8-bit precision sqrt table
-
- .CODE INTMATH
-
-
- MULT29 MACRO a,b ; multiply <3.29> -> eax
- mov eax,DWORD PTR a
- imul DWORD PTR b
- shrd eax,edx,29
- adc eax,0
- ENDM
-
- MMULT29 MACRO a,b,c ; multiply 3 of <3.29> -> eax
- mov eax,DWORD PTR a
- imul DWORD PTR b
- shrd eax,edx,29
- adc eax,0
- imul DWORD PTR c
- shrd eax,edx,29
- adc eax,0
- ENDM
-
- DOTPROD MACRO a,b,c,x,y,z,p ; dot product plus p, accum in ecx:ebx
- mov eax,a ; result in eax
- imul DWORD PTR x
- mov ecx,edx
- mov ebx,eax
- mov eax,b
- imul DWORD PTR y
- add ebx,eax
- adc ecx,edx
- mov eax,c
- imul DWORD PTR z
- add eax,ebx
- adc edx,ecx
- shrd eax,edx,29
- adc eax,p
- ENDM
-
-
- ;/************ COLLISION DETECTION AND SELECTION ***********/
-
- ;long sphere_pretest(OBJECT *obj, long x, long y, long z)
- ; tests 3D selection point for best object to select */
- ; returns 0x7FFFFFFF if not in obj bounds, else
- ; returns abs(x1-x2) + abs(y1-y2) + abs(z1-z2)
- ; <conservative closeness: always greater than actual>
-
-
- obj equ [bp+8] ; arguments
- x equ [bp+12]
- y equ [bp+16]
- z equ [bp+20]
-
- sx equ es:[di].O_sphx
- sy equ es:[di].O_sphy
- sz equ es:[di].O_sphz
- sr equ es:[di].O_sphr
-
-
- PUBLIC _sphere_pretest
-
- _sphere_pretest proc far
-
- .386
- push ebp
- mov ebp,esp
-
- push ecx
- push edi
-
- les di,DWORD PTR obj ; ptr to object
-
- mov eax,sx ;/* x bounds */
- sub eax,x
- cmp eax,sr
- jg notin
- neg eax
- cmp eax,sr
- jg notin
-
- mov eax,sy ;/* y bounds */
- sub eax,y
- cmp eax,sr
- jg notin
- neg eax
- cmp eax,sr
- jg notin
-
- mov eax,sz ;/* z bounds */
- sub eax,z
- cmp eax,sr
- jg notin
- neg eax
- cmp eax,sr
- jg notin
-
- imul eax ;/* square of distance to center */
- mov ebx,eax
- mov ecx,edx
-
- mov eax,sx
- sub eax,x
- imul eax
- add ebx,eax
- adc ecx,edx
-
- mov eax,sy
- sub eax,y
- imul eax
- add ebx,eax
- adc ecx,edx
-
- mov eax,sr ;/* square of radius */
- imul eax
- cmp edx,ecx
- ja in
- jb notin
- cmp eax,ebx
- jae in
- notin: ;/* outside of sphere */
- mov eax,07FFFFFFFh; ;/* big never wins */
- jmp retlarge
- in:
- ;test ebx,-1 ;/* shift so denom. is 32-bit or less */
- ;jz nolo1
- ;mov eax,edx
- ;xor edx,edx
- ;mov ebx,ecx
- ;xor ecx,ecx
- ;nolo1:
- mov eax,x ;/* abs(x-sx)+abs(y-sy)+abs(z-sz) approx. dist from center */
- sub eax,sx
- cdq
- xor eax,edx
- sub eax,edx
- mov ebx,eax
-
- mov eax,y
- sub eax,sy
- cdq
- xor eax,edx
- sub eax,edx
- add ebx,eax
-
- mov eax,z
- sub eax,sz
- cdq
- xor eax,edx
- sub eax,edx
- add ebx,eax
-
- mov eax,ebx
- retlarge:
- shld edx,eax,16 ; return in eax and dx:ax
-
- pop edi
- pop ecx
-
- mov esp,ebp
- pop ebp
- ret
-
- _sphere_pretest endp
-
-
- ;/************* POLYGON NORMAL COMPUTATION *************/
-
-
- ; /* compute, unitize (3.29 format) normal to plane. */
- ; /* returns -1 if normal is zero, else log2(length) */
- ;int find_normal(long x1, long y1, long z1,
- ; long x2, long y2, long z2,
- ; long x3, long y3, long z3,
- ; long *xn, long *yn, long *zn)
- ; extern int sqrtable[1024];
-
-
- x1 equ [bp+8] ; arguments
- y1 equ [bp+12]
- z1 equ [bp+16]
- x2 equ [bp+20]
- y2 equ [bp+24]
- z2 equ [bp+28]
- x3 equ [bp+32]
- y3 equ [bp+36]
- z3 equ [bp+40]
- xn equ [bp+44]
- yn equ [bp+48]
- zn equ [bp+52]
-
- xh equ [bp-4] ; locals
- xl equ [bp-8]
- yh equ [bp-12]
- yl equ [bp-16]
- zh equ [bp-20]
- zl equ [bp-24]
- xah equ [bp-28]
- xal equ [bp-32]
- yah equ [bp-36]
- yal equ [bp-40]
- zah equ [bp-44]
- zal equ [bp-48]
- length equ [bp-52]
-
- PUBLIC _find_normal
-
- _find_normal proc far
-
- .386
- push ebp
- mov ebp,esp
- sub esp,60
-
- push esi
- push edi
- push ecx
- push edx
-
- mov eax,y2 ;/* compute 64-bit cross product */
- sub eax,y1 ;/* and also abs. value for shifts */
- mov ecx,z3
- sub ecx,z2
- imul ecx
- mov edi,edx
- mov esi,eax
- mov eax,y3
- sub eax,y2
- mov ecx,z2
- sub ecx,z1
- imul ecx
- sub esi,eax
- sbb edi,edx
- mov xh,edi
- mov xl,esi
- jge stax
- not edi
- not esi
- add esi,1
- adc edi,0
- stax:
- mov xah,edi
- mov xal,esi
-
- mov eax,z2
- sub eax,z1
- mov ecx,x3
- sub ecx,x2
- imul ecx
- mov edi,edx
- mov esi,eax
- mov eax,z3
- sub eax,z2
- mov ecx,x2
- sub ecx,x1
- imul ecx
- sub esi,eax
- sbb edi,edx
- mov yh,edi
- mov yl,esi
- jge stay
- not edi
- not esi
- add esi,1
- adc edi,0
- stay:
- mov yah,edi
- mov yal,esi
-
- mov eax,x2
- sub eax,x1
- mov ecx,y3
- sub ecx,y2
- imul ecx
- mov edi,edx
- mov esi,eax
- mov eax,x3
- sub eax,x2
- mov ecx,y2
- sub ecx,y1
- imul ecx
- sub esi,eax
- sbb edi,edx
- mov zh,edi
- mov zl,esi
- jge staz
- not edi
- not esi
- add esi,1
- adc edi,0
- staz:
- mov zah,edi
- mov zal,esi
- ;/* now normalize to 3.29 */
- or esi,yal
- or esi,xal
- or edi,yah
- or edi,xah
- jz zero_h
-
- xor ax,ax ;/* ax is shift count */
- test edi,0FFFF0000h ;/* top word not zero: cnvt to 1.n <3.29> */
- jz z16h
- add ax,16
- shr edi,16
- z16h:
- test di,0FF00h
- jz z8h
- add ax,8
- shr edi,8
- z8h:
- shl edi,8 ;/* most ecomonical pos'n */
- bsr cx,di ;/* get exact shift */
- sub cx,5
- add cx,ax
-
- mov eax,xh ;/* convert cross product to 1.n */
- shrd xl,eax,cl
- mov eax,yh
- shrd yl,eax,cl
- mov eax,zh
- shrd zl,eax,cl
-
- add cx,29
- mov length,cx
-
- jmp dshnorm
- zero_h:
- or esi,esi
- jz zero_normal
- mov ax,24
- test esi,0FFFF0000h ;/* top word is zero: cnvt to 1.n <3.29> */
- jz z16l
- sub ax,16
- shr esi,16
- z16l:
- test si,0FF00h
- jz z8l
- sub ax,8
- shr esi,8
- z8l:
- shl esi,8 ;/* most ecomonical pos'n */
- bsr cx,si ;/* get exact shift */
- neg cx
- add cx,13
- add cx,ax
-
- jz noshiftl
- jg lshiftl
-
- neg cx
- mov eax,xh ;/* convert cross product to 1.n */
- shrd xl,eax,cl ;/* need ext. for borderline cases */
- mov eax,yh
- shrd yl,eax,cl
- mov eax,zh
- shrd zl,eax,cl
- noshiftl:
- add cx,29
- mov length,cx
- jmp dshnorm
- lshiftl:
- shl DWORD PTR xl,cl
- shl DWORD PTR yl,cl
- shl DWORD PTR zl,cl
-
- mov ax,29
- sub ax,cx
- mov length,ax
- dshnorm:
- jmp finish
-
- zero_normal:
- mov eax,1 ; *xn = *yn = *zn = -1
- mov xn,eax
- mov yn,eax
- mov zn,eax
- mov WORD PTR length,0 ; return 0
- jmp rtn_result
-
- finish: ;/* compute magnitude, convert to unit length */
- mov eax,xl ;/* compute squares */
- sar eax,16
- imul ax
- mov bx,dx
- mov cx,ax
-
- mov eax,yl
- sar eax,16
- imul ax
- add cx,ax
- adc bx,dx
-
- mov eax,zl
- sar eax,16
- imul ax
- add cx,ax
- adc bx,dx
-
- shr bx,4 ;/* magnitude << 13 */
- shl bx,1
- les si,DWORD PTR _sqrtable
- mov cx,WORD PTR es:[bx+si]
-
- movzx ecx,cx
-
- mov eax,xl ;/* scale cross product */
- cdq
- shld edx,eax,13
- shl eax,13
- idiv ecx
- mov xl,eax
-
- mov eax,yl
- cdq
- shld edx,eax,13
- shl eax,13
- idiv ecx
- mov yl,eax
-
- mov eax,zl
- cdq
- shld edx,eax,13
- shl eax,13
- idiv ecx
- mov zl,eax
-
- rtn_result: ; /* left-hand coordinate system: negate normal */
- les bx,DWORD PTR xn
- mov eax,xl
- neg eax
- mov DWORD PTR es:[bx],eax
-
- les bx,DWORD PTR yn
- mov eax,yl
- neg eax
- mov DWORD PTR es:[bx],eax
-
- les bx,DWORD PTR zn
- mov eax,zl
- neg eax
- mov DWORD PTR es:[bx],eax
-
- mov ax, length
-
- pop edx
- pop ecx
- pop edi
- pop esi
-
- mov esp,ebp
- pop ebp
- ret
-
- _find_normal endp
-
-
-
- ;/******************** APPLY MATRIX TO OBJECTS **************/
-
-
- ;void matmove_osphere(OBJECT *obj, MATRIX m)
-
- obj equ [bp+8] ; arguments
- m equ [bp+12]
-
- PUBLIC _matmove_osphere
-
- _matmove_osphere proc far
-
- .386
- push ebp
- mov ebp,esp
-
- push ds
- push esi
- push edi
- push ecx
- push edx
-
- lds si,DWORD PTR m ; PTR TO MATRIX
-
- les di,DWORD PTR obj ; ptr to object
-
- inc DWORD PTR es:[bx].O_ucount ; mark as moved
-
- DOTPROD ds:[si],ds:[si+4],ds:[si+8],es:[di].O_osphx,es:[di].O_osphy,es:[di].O_osphz,ds:[si+36]
- mov es:[di].O_sphx,eax
-
- DOTPROD ds:[si+12],ds:[si+16],ds:[si+20],es:[di].O_osphx,es:[di].O_osphy,es:[di].O_osphz,ds:[si+40]
- mov es:[di].O_sphy,eax
-
- DOTPROD ds:[si+24],ds:[si+28],ds:[si+32],es:[di].O_osphx,es:[di].O_osphy,es:[di].O_osphz,ds:[si+44]
- mov es:[di].O_sphz,eax
-
- pop edx
- pop ecx
- pop edi
- pop esi
- pop ds
-
- mov esp,ebp
- pop ebp
- ret
-
- _matmove_osphere endp
-
-
-
-
- ;void matmove_rep(REP *rep, MATRIX m)
-
- rep equ [bp+8] ; arguments
- m equ [bp+12]
-
- i equ [bp-4] ; locals
- v equ [bp-8]
- p equ [bp-12]
- vc equ [bp-14]
- pc equ [bp-16]
-
- vs equ SIZE VERTEX ; structure sizes
- ps equ SIZE POLY
-
- PUBLIC _matmove_rep
-
- _matmove_rep proc far
-
- .386
- push ebp
- mov ebp,esp
- sub esp,20
-
- push ds
- push esi
- push edi
- push ecx
- push edx
-
- lds si,DWORD PTR m ; PTR TO MATRIX
-
- les di,DWORD PTR rep ; ptr to rep
-
- mov eax, es:[di].R_verts ; get data
- mov v, eax
- mov eax, es:[di].R_polys
- mov p, eax
- mov ax, es:[di].R_nverts
- mov vc, ax
- mov ax, es:[di].R_npolys
- mov pc, ax
-
- les di,DWORD PTR v ;/* rotate/translate all vertices */
-
- vconv:
- DOTPROD ds:[si],ds:[si+4],ds:[si+8],es:[di].V_ox,es:[di].V_oy,es:[di].V_oz,ds:[si+36]
- mov es:[di].V_x,eax
-
- DOTPROD ds:[si+12],ds:[si+16],ds:[si+20],es:[di].V_ox,es:[di].V_oy,es:[di].V_oz,ds:[si+40]
- mov es:[di].V_y,eax
-
- DOTPROD ds:[si+24],ds:[si+28],ds:[si+32],es:[di].V_ox,es:[di].V_oy,es:[di].V_oz,ds:[si+44]
- mov es:[di].V_z,eax
-
- add di,vs
- dec WORD PTR vc
- jnz vconv
-
- les di,DWORD PTR p ; now for polys: rotate all normals */
-
- pconv:
- DOTPROD ds:[si],ds:[si+4],ds:[si+8],es:[di].P_onormx,es:[di].P_onormy,es:[di].P_onormz,0
- mov es:[di].P_normx,eax
-
- DOTPROD ds:[si+12],ds:[si+16],ds:[si+20],es:[di].P_onormx,es:[di].P_onormy,es:[di].P_onormz,0
- mov es:[di].P_normy,eax
-
- DOTPROD ds:[si+24],ds:[si+28],ds:[si+32],es:[di].P_onormx,es:[di].P_onormy,es:[di].P_onormz,0
- mov es:[di].P_normz,eax
-
- add di,ps
- dec WORD PTR pc
- jnz pconv
-
- pop edx
- pop ecx
- pop edi
- pop esi
- pop ds
-
- mov esp,ebp
- pop ebp
- ret
-
- _matmove_rep endp
-
-
- end
-
-
-